package com.woniuxy.usercoachassemble.proxy;

import com.woniuxy.usercoachassemble.annotation.NoRepeatSubmit;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.example.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

/**
 * ClassName: NoRepeatSubmitAop
 * Description: 防止表单重复提交动态代理类
 * date: 2020/7/11 16:44
 *
 * @author Fy浪迹、
 */
@Component
@Aspect
@Slf4j
public class NoRepeatSubmitAop {
    @Autowired
    public StringRedisTemplate redisTemplate;

    @Around("execution(* com.woniuxy.usercoachassemble.controller.*Controller.*(..)) && @annotation(nrs)")
    public Object arround(ProceedingJoinPoint pjp, NoRepeatSubmit nrs) {
        ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            String sessionId = RequestContextHolder.getRequestAttributes().getSessionId();
            HttpServletRequest request = attributes.getRequest();
            String key = sessionId + "-" + request.getServletPath();
            if (opsForValue.get(key) == null) {// 如果缓存中有这个url视为重复提交
                opsForValue.set(key, "0", 10, TimeUnit.SECONDS);
                Object o = pjp.proceed();

                opsForValue.set(key,"0",500,TimeUnit.MILLISECONDS);
                return o;
            } else {
                log.error("重复提交");
                Result result = Result.Error(600, "请勿重复提交表单");
                return result;
            }
        } catch (Throwable e) {
            e.printStackTrace();
            log.error("验证重复提交时出现未知异常!");
            return "{\"code\":-889,\"message\":\"验证重复提交时出现未知异常!\"}";
        }
    }
}
